﻿////////////////////////////////////////////////////////////
//To add a new algorithm:
//  Instancieer de filter
//  Voeg hem toe aan de AlgorithmList
//  Maak nieuwe toolStripMenuItem en zet daarin de functie startAlgorithm(algorithm);

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;

namespace Team3_ProjectGUIFinal
{
    public partial class Nummerbord : Form
    {

        int sourceArrayCounter = 0;
        int arrayCounter = 0;
        PictureBox[] sourceImages;
        PictureBox[] oldImage = new PictureBox[5];
        PictureBox[] temp;
        Bitmap[] sourceBitmapMultiple;
        Boolean[] selectedImage;

        Size multipleImageSize = new Size(1257, 635);
        Size startSize = new Size(1136, 635);
        Bitmap sourceBitmap, inputBitmap, outputBitmap;
        Stopwatch sp;

        public static List<Algorithm> combinedFilterList = new List<Algorithm>();

        //Forms
        Form hf;
        Form cf;

        //New algorithms
        List<Algorithm> AlgorithmList = new List<Algorithm>();
        OldLocateAlgorithm ola = new OldLocateAlgorithm("Old Locate Algorithm");
        FinalLocateAlgorithm fla = new FinalLocateAlgorithm("Final Locate Algorithm");
        LocateDebug ld = new LocateDebug("Locate Debug");
        EqualisationAlgorithm eq = new EqualisationAlgorithm("equalisation");

        public Nummerbord()
        {
            InitializeComponent();
            SourceImagePanel.Hide();
            this.Size = startSize;
            AlgorithmList.Add(ola);
            AlgorithmList.Add(ld);
            AlgorithmList.Add(fla);
            AlgorithmList.Add(eq);
        }

        private void closeApplicationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void openFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openImage())
            {
                SourceImagePanel.Hide();
                PicturePanel.Controls.Clear();
                arrayCounter = 0;
                oldImage = new PictureBox[5];
                AddPictureToPanel(InputPictureBox.Image);
                filterToolStripMenuItem.Enabled = true;
            }
        }
        private Boolean openImage()
        {
            Boolean succes = false;
            OpenFileDialog oFD = new OpenFileDialog();
            //oFD.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            oFD.Filter = "Image Files(*.BMP;*.JPG;*.JPEG;*.PNG;)|*.BMP;*.JPG;*.JPEG;*.PNG;";
            oFD.Title = "Browse your image";
            oFD.FilterIndex = 1;
            oFD.RestoreDirectory = true;
            if (oFD.ShowDialog() == DialogResult.OK)
            {
                String CurrentFileName = Path.GetFullPath(oFD.FileName);
                sourceBitmap = new Bitmap(CurrentFileName);
                inputBitmap = new Bitmap(CurrentFileName);
                outputBitmap = new Bitmap(CurrentFileName);
                InputPictureBox.Image = inputBitmap;
                InfoTextField.Text = "";
                OutputPictureBox.Image = null;
                succes = true;
            }
            return succes;
        }


        private void openMultipleFilesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openMultipleImage())
            {
                filterToolStripMenuItem.Enabled = false;
                SourceImagePanel.Show();
                PicturePanel.Controls.Clear();
                arrayCounter = 0;
                sourceArrayCounter = 0;
                oldImage = new PictureBox[5];
                this.Size = multipleImageSize;
            }
        }
        private Boolean openMultipleImage()
        {
            Boolean succes = false;
            OpenFileDialog oFD = new OpenFileDialog();
            //oFD.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            oFD.Filter = "Image Files(*.BMP;*.JPG;*.JPEG;*.PNG;)|*.BMP;*.JPG;*.JPEG;*.PNG;";
            oFD.Title = "Browse your images";
            oFD.Multiselect = true;

            if (oFD.ShowDialog() == DialogResult.OK)
            {
                int count = 0;
                foreach (String file in oFD.FileNames) { count++; }
                int counter = 0;
                sourceBitmapMultiple = new Bitmap[count];
                sourceImages = new PictureBox[count];
                selectedImage = new Boolean[count];
                SourceImagePanel.Controls.Clear();

                foreach (String file in oFD.FileNames)
                {
                    sourceBitmapMultiple[counter] = new Bitmap(file);
                    AddPictureToSourcePanel(sourceBitmapMultiple[counter]);
                    InputPictureBox.Image = null;
                    InfoTextField.Text = "";
                    OutputPictureBox.Image = null;
                    counter++;
                }
                succes = true;
            }

            return succes;
        }

        private void AddPictureToSourcePanel(Image Picture)
        {
            int myself = sourceArrayCounter;
            sourceImages[sourceArrayCounter] = new PictureBox();
            sourceImages[sourceArrayCounter].Image = Picture;
            sourceImages[sourceArrayCounter].SizeMode = PictureBoxSizeMode.Zoom;
            sourceImages[sourceArrayCounter].BorderStyle = BorderStyle.FixedSingle;
            sourceImages[sourceArrayCounter].Height = 100;
            sourceImages[sourceArrayCounter].Width = 100;
            sourceImages[sourceArrayCounter].BackColor = Color.White;
            sourceImages[sourceArrayCounter].DoubleClick += (sender, args) => sourceImage_doubleClick(sender, args, myself);
            sourceImages[sourceArrayCounter].MouseDown += (sender, args) => sourceImage_Click(sender, args, myself);
            SourceImagePanel.Controls.Add(sourceImages[sourceArrayCounter]);
            sourceArrayCounter++;
        }

        private void AddPictureToPanel(Image Picture)
        {
            if (arrayCounter < oldImage.Length)
            {
                int myself = arrayCounter;
                oldImage[arrayCounter] = new PictureBox();
                oldImage[arrayCounter].Image = Picture;
                oldImage[arrayCounter].SizeMode = PictureBoxSizeMode.Zoom;
                oldImage[arrayCounter].BorderStyle = BorderStyle.FixedSingle;
                oldImage[arrayCounter].Height = 100;
                oldImage[arrayCounter].Width = 100;
                oldImage[arrayCounter].BackColor = Color.White;
                oldImage[arrayCounter].DoubleClick += (sender, args) => oldImage_doubleClick(sender, args, myself);
                oldImage[arrayCounter].MouseDown += (sender, args) => oldImage_Click(sender, args, myself);
                PicturePanel.Controls.Add(oldImage[arrayCounter]);
                arrayCounter++;
            }
            else
            {
                temp = new PictureBox[oldImage.Length];
                for (int i = 0; i < oldImage.Length; i++)
                {
                    temp[i] = oldImage[i];
                }
                oldImage = new PictureBox[oldImage.Length + 5];
                for (int i = 0; i < temp.Length; i++)
                {
                    oldImage[i] = temp[i];
                }
                AddPictureToPanel(Picture);
            }
        }

        private void inputPictureBox_Click(object sender, EventArgs e)
        {
            previewImage(InputPictureBox);
        }

        private void previewImage(PictureBox PreviewPictureBox)
        {
            if (PreviewPictureBox.Image != null)
            {
                Form previewImageForm = new previewImageForm(PreviewPictureBox.Image);
                previewImageForm.Show();
            }
        }

        private void OutputPictureBox_Click(object sender, EventArgs e)
        {
            previewImage(OutputPictureBox);
        }

        public void startAlgorithm(Algorithm algo)
        {
            Nummerbord.ActiveForm.Enabled = false;
            sp = Stopwatch.StartNew();
            outputBitmap = new Bitmap(algo.DoAlgorithm(inputBitmap));
            sp.Stop();
            Nummerbord.ActiveForm.Enabled = true;
            InfoTextField.Text += algo.getName() + " took: " + sp.ElapsedMilliseconds + " ms\n\n";
            OutputPictureBox.Image = outputBitmap;
            ToIntputButton.Enabled = true;
        }

        private void ToIntputButton_Click(object sender, EventArgs e)
        {
            AddPictureToPanel(OutputPictureBox.Image);
            inputBitmap = outputBitmap;
            InputPictureBox.Image = inputBitmap;
            OutputPictureBox.Image = null;
            ToIntputButton.Enabled = false;
        }

        public void oldImage_Click(object sender, MouseEventArgs e, int index)
        {
            if (e.Button == MouseButtons.Right)
            {
                inputBitmap = new Bitmap((Bitmap)oldImage[index].Image);
                InputPictureBox.Image = inputBitmap;
                outputBitmap = null;
                OutputPictureBox.Image = outputBitmap;
            }
        }

        public void oldImage_doubleClick(object sender, EventArgs e, int index)
        {
            previewImage(oldImage[index]);
        }

        public void sourceImage_Click(object sender, MouseEventArgs e, int index)
        {
            if (e.Button == MouseButtons.Right)
            {
                inputBitmap = new Bitmap((Bitmap)sourceImages[index].Image);
                InputPictureBox.Image = inputBitmap;
                outputBitmap = null;
                OutputPictureBox.Image = outputBitmap;
                filterToolStripMenuItem.Enabled = true;
                ToIntputButton.Enabled = false;
            }
            else if (e.Button == MouseButtons.Left)
            {
                //Selection
                if (selectedImage[index])
                {
                    selectedImage[index] = false;
                    sourceImages[index].BackColor = Color.White;
                }
                else
                {
                    selectedImage[index] = true;
                    sourceImages[index].BackColor = Color.Blue;
                }
            }
        }

        public void sourceImage_doubleClick(object sender, EventArgs e, int index)
        {
            previewImage(sourceImages[index]);
        }

        private void helpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            hf = new helpForm();
            hf.Show();
        }

        private void combineFiltersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            cf = new combineFiltersForm(AlgorithmList, combinedFilterList);
            cf.Show();
        }

        private void combinedFilterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int filterLen = combinedFilterList.Count;
            if (filterLen != 0)
            {
                foreach (Algorithm a in combinedFilterList)
                {
                    startAlgorithm(a);
                    AddPictureToPanel(OutputPictureBox.Image);
                    inputBitmap = outputBitmap;
                    InputPictureBox.Image = inputBitmap;
                }
                OutputPictureBox.Image = null;
                ToIntputButton.Enabled = false;
            }
            else
            {
                MessageBox.Show("Please combine filters to use this filter");
            }
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void locateDebugToolStripMenuItem_Click(object sender, EventArgs e)
        {
            startAlgorithm(ld);
        }

        private void equalisationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            startAlgorithm(eq);
        }

        private void finalLocateAlgorithmToolStripMenuItem_Click(object sender, EventArgs e)
        {
            startAlgorithm(fla);
        }

        private void oldLocateAlgorithmToolStripMenuItem_Click(object sender, EventArgs e)
        {
            startAlgorithm(ola);
        }
    }
}
